package com.szholly.utils.freemarker;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.BeansException;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig;

import com.szholly.utils.freemarker.directive.IDirective;
import com.szholly.utils.spring.SpringBeanFactory;

import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.ext.jsp.TaglibFactory;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * 定义Freemarker的模板查找策略
 */
public class FreeMarkerView extends org.springframework.web.servlet.view.freemarker.FreeMarkerView {

	/**
	 * 部署路径属名称
	 */
	public static final String CONTEXT_PATH = "base";
	
	/**
	 * 生成html缓存的目录
	 */
	private String htmlCachePath = null;
	
	/**
	 * 是否生成html缓存
	 */
	private String createHtmlCache = null;
	
	/**
	 * 在model中增加部署路径base，方便处理部署路径问题
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected void exposeHelpers(Map model, HttpServletRequest request)
			throws Exception {
		super.exposeHelpers(model, request);
		model.put(CONTEXT_PATH, request.getContextPath());
	}
	
	protected void initServletContext(ServletContext servletContext) throws BeansException {
		if (getConfiguration() != null) {
			new TaglibFactory(servletContext);
		} else {
			FreeMarkerConfig config = autodetectConfiguration();
			ClassTemplateLoader ctl = new ClassTemplateLoader(this.getClass(), "/");
			TemplateLoader tl = config.getConfiguration().getTemplateLoader();
			TemplateLoader[] loaders = new TemplateLoader[] { tl, ctl };
			MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);
			config.getConfiguration().setTemplateLoader(mtl);
			setConfiguration(config.getConfiguration());
			config.getTaglibFactory();
		}
	}
	
	@Override
	protected void doRender(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// TODO Auto-generated method stub
		super.doRender(model, request, response);
		
		if(createHtmlCache == null){
//			createHtmlCache = lrq.common.PropertiesUnit.getValue("createHtmlCache");
		}
		
		if(htmlCachePath == null){
//			htmlCachePath = lrq.common.PropertiesUnit.getValue("htmlCachePath");
		}
		 System.out.println("createHtmlCache:"+createHtmlCache);
		 System.out.println("htmlCachePath:"+htmlCachePath);
		if(htmlCachePath == null || createHtmlCache == null){
			return;
		}
		
		createHtmlCache = createHtmlCache.toUpperCase();
		
		if("TRUE".equals(createHtmlCache)){
			String getRealPath = request.getSession().getServletContext().getRealPath("/");
			 String getServletPath = request.getServletPath();	
			 
			 String tempBasePath = getRealPath.replaceAll("\\\\","/")+"WEB-INF/";
			 String tempFile = "/view/"+getServletPath.replaceAll(".do", ".html");
			 
			 createFile(tempBasePath, tempFile, model);
			 
			 System.out.println("生成html，路径:"+tempBasePath+tempFile);
		}
	}
	
	public void createFile(String tempFilePath,String tempFileName,Map<String, Object> model) throws IOException, TemplateException{
		
		Configuration cfg = new Configuration();		
		cfg.setDirectoryForTemplateLoading(new File(tempFilePath));
		cfg.setDefaultEncoding("UTF-8"); 
		Template temp = cfg.getTemplate(tempFileName, "UTF-8");
		temp.setEncoding("UTF-8");
		if(tempFileName.split("/").length > 0){
			String dirPath = tempFileName.substring(0,tempFileName.lastIndexOf("/"));
			System.out.println("目录："+htmlCachePath+dirPath);
			File htmlDir = new File(htmlCachePath+dirPath);
			if(!htmlDir.exists()){
				htmlDir.mkdirs();
			}
		}
		
		tempFileName = tempFileName.replaceAll(".html", ".do");
		
		FileOutputStream fileOut = new FileOutputStream(htmlCachePath+tempFileName);
		
		OutputStreamWriter writer = new OutputStreamWriter(fileOut,"UTF-8");		

		Map<String, Object> directives = getFreemarkerVariables();
		model.putAll(directives);
		
		temp.process(model, writer);
		writer.flush();
		writer.close();
		fileOut.close();
	}
	
	public Map<String, Object> getFreemarkerVariables(){
		Map<String, Object> value = new HashMap<String,Object>();
		@SuppressWarnings("rawtypes")
		Map tableMap = SpringBeanFactory.getBeansByType(IDirective.class);
		@SuppressWarnings("unchecked")
		Set<String> keySet = tableMap.keySet();
		for (String item : keySet) {
			Object directive = tableMap.get(item);
			String[] msgs = item.split("_");
			if(msgs.length==2){
				String key = msgs[1];
				if(value.containsKey(key)){
					value.remove(key);
				}
				value.put(key, directive);
			}
		}
		return value;
	}
}
